import cmStyleMixin from '@/mixins/cmStyle.js'
import commonMixin from '@/mixins/common.js'

// 浮动按钮的边距
const FLOAT_PADDING = 10

export default {
  name: 'cm-float',
  mixins: [
    cmStyleMixin,
    commonMixin
  ],
  props: {
    // 按钮的位置
    position: {
      type: String,
      default: 'top',
      validator (value) {
        // 这个值必须匹配下列字符串中的一个
        return ['top', 'bottom', 'left', 'right', 'left-top', 'right-top', 'left-bottom', 'right-bottom'].indexOf(value) !== -1
      }
    },
    // 按钮容器直径
    size: {
      type: [Number, String],
      default: 60
    },
    // 内部ICON标签大小
    iconSize: {
      type: [Number, String],
      default: 24
    },
    // 按钮容器之间的间隔
    margin: {
      type: [Number, String],
      default: 10
    },
    // 按钮容器距离四个边界的距离
    top: {
      type: [Number, String],
      default: FLOAT_PADDING
    },
    bottom: {
      type: [Number, String],
      default: FLOAT_PADDING
    },
    left: {
      type: [Number, String],
      default: FLOAT_PADDING
    },
    right: {
      type: [Number, String],
      default: FLOAT_PADDING
    },
    /* 
      数据列表，若有多组，则渲染成折叠对象，每一个对象属性如下
      icon 标签
      text 文字
      img 图片，优先级高于icon
      size 标签的大小
      width 图片宽 CSS
      height 图片高 CSS
      type 指定按钮样式
      outlined 指定按钮样式
      border 指定按钮样式
      badgeTxt badgeMax badgeMin 传给cmBadge组件
    */
    items: {
      type: Array,
      default () {
        return []
      }
    },
    // 折叠滑出方向
    foldDirection: {
      type: String,
      default: 'none-hor',
      validator (value) {
        /* 
          这个值必须匹配下列字符串中的一个
          non-hor 不折叠，水平排列
          non-ver 不折叠，竖直排列
        */
        return ['up', 'down', 'left', 'right', 'none-hor', 'none-ver'].indexOf(value) !== -1
      }
    },
    // 折叠动画持续时间
    aniDuration: {
      type: Number,
      default: 300
    }
  },
  data () {
    return {      
      // 接受数据内容，传给button组件
      itemsData: [],
      // 每一个对象的样式
      itemsStyle: [],
      // 触发器ICON的样式
      triggerStyle: {
        transition: `transform ${this.aniDuration}ms ease`,
      },
      
      // 折叠状态
      isFolded: false,
      // 是否正在播放折叠动画
      isFolding: false,
    }
  },
  computed: {
    // 是否折叠
    isFolder () {
      return this.foldDirection.indexOf('none') < 0
    },
    
    // 容器的尺寸样式
    sizeStyle () {
      let style = {}
      if (this.isFolder) {
        // 启用折叠的情况下，只留有一个按钮的空间
        return {
          width: this.size + 'px',
          height: this.size + 'px'
        }        
      }
      // 不启用折叠的情况下，留有多个按钮的空间
      const itemNum = this.itemsData.length
      const extraWidth = (itemNum - 1) * (this.size + this.margin)
      if (this.foldDirection.indexOf('hor') >= 0) {
        return {
          width: (this.size + extraWidth) + 'px',
          height: this.size + 'px'
        }
      }
      return {
        width: this.size + 'px',
        height: (this.size + extraWidth) + 'px'
      }
    },
    
    // 容器的定位样式
    posStyle () {
      let style = {}
      if (this.position.indexOf('top') >= 0) {
        style.top = this.top + 'px'
      }
      if (this.position.indexOf('bottom') >= 0) {
        style.bottom = this.bottom + 'px'
      }
      if (this.position.indexOf('left') >= 0) {
        style.left = this.left + 'px'
      }
      if (this.position.indexOf('right') >= 0) {
        style.right = this.right + 'px'
      }
      
      if (this.position === 'top' || this.position === 'bottom') {
        style.left = '50%'
        style.transform = 'translate(-50%, 0)'
      }
      if (this.position === 'left' || this.position === 'right') {
        style.top = '50%'
        style.transform = 'translate(0, -50%)'
      }
      return style
    },
  },
  methods: {
    // 初始化单元数据
    initItems () {
      if (this.isFolder) {
        // 若为折叠对象，则第一个对象是折叠按钮
        this.itemsData.push({
          icon: this.foldDirection === 'left' ? 'iconfont icon-arrow-lift' : `iconfont icon-arrow-${this.foldDirection}`
        })
        this.itemsData = this.itemsData.concat(this.items)
      }
      else {
        this.itemsData = this.items
      }
      
      // 初始化对象样式
      const len = this.itemsData.length
      for (let i = 0; i < len; i++) {
        const style = this.itemPosStyle(i)
        
        this.itemsStyle.push(style)
      }
      
      // 初始化单元数据，补齐不存在但是必要的字段的字段
      this.$u.obj.fillObjectArr(this.itemsData, {
        // 默认主色调
        type: 'primary',
        // 默认不镂空
        outlined: false,
        // 默认有边框
        border: true,
        // 默认有阴影
        shadow: true,
        // 标签大小
        size: this.iconSize,
        // 图片大小
        width: this.iconSize + 'px',
        height: this.iconSize + 'px'
      })
    },
    
    // 按钮单元的定位样式
    itemPosStyle (index) {
      if (this.isFolder) {
        // 启用折叠的情况下
        let style = {
          top: '0',
          bottom: '0',
          left: '0',
          right: '0'
        }
        if (index > 0) {
          style.visibility = 'hidden'
          style.transition = `transform ${this.aniDuration}ms ease`
        }
        else {
          style.zIndex = 10
        }
        // 启用折叠的情况下
        return style
      }
      
      // 不启用折叠的情况下
      let style = {
        width: this.size + 'px',
        height: this.size + 'px'
      }
      const offset = index * (parseInt(this.size) + parseInt(this.margin))
      if (this.foldDirection.indexOf('hor') >= 0) {
        style.left = offset + 'px'
      }
      else {
        style.top = offset + 'px'
      }
      return style
    },
    
    // 点击回调事件
    clickHandler (item, index) {
      if (this.isFolder && index === 0 && !this.isFolding) {
        this.isFolding = true
        if (this.isFolded) {
          // 当前折叠展开，需要关闭折叠，触发折叠动画
          this.isFolded = false
        }
        else {
          // 开启折叠
          this.isFolded = true
          // 显示折叠对象
          this.foldVisibleControl(true)
        }
        // 折叠动画
        this.foldAnimate()
        this.wait(this.aniDuration, 'float-ani').then(() => {
          // 若收回折叠，需要隐藏折叠动画
          if (!this.isFolded) {
            this.foldVisibleControl(false)
          }
          // 动画完成
          this.isFolding = false
        })
        .catch((e) => {
          console.log(e)
        })
      }
      // 触发点击事件
      this.$emit('click', item, index)
    },
    
    // 更新折叠动画
    foldAnimate () {
      // 折叠触发开关的动画
      if (this.isFolded) {
        this.$set(this.triggerStyle, 'transform', 'rotate(180deg)')
      }
      else {
        this.$delete(this.triggerStyle, 'transform')
      }
      
      // 折叠对象的动画
      const len = this.itemsData.length
      for (let i = 1; i < len; i++) {
        if (this.isFolded) {
          let distance = i * (parseInt(this.size) + parseInt(this.margin))
          if (this.foldDirection === 'up' || this.foldDirection === 'left') {
            distance = distance * (-1)
          }
          let translateMethod = 'translateX'
          if (this.foldDirection === 'down' || this.foldDirection === 'up') {
            translateMethod = 'translateY'
          }
          this.$set(this.itemsStyle[i], 'transform', `${translateMethod}(${distance}px)`)          
        }
        else {
          this.$delete(this.itemsStyle[i], 'transform')
        }
      }
    },
    
    // 控制折叠对象的显示隐藏
    foldVisibleControl (isShow = true) {
      const len = this.itemsData.length
      for (let i = 1; i < len; i++) {
        if (isShow) {
          this.$set(this.itemsStyle[i], 'visibility', 'visible')
        }
        else {
          this.$set(this.itemsStyle[i], 'visibility', 'hidden')
        }
      }
    },
    
    getItemStyle (index) {
      return this.itemsStyle[index]
    }
  },
  created () {
    this.initItems()
  }
}